import Hls from 'hls.js';

/**
 * HLS 视频播放器类
 * 用于播放 HLS 格式的视频流
 */
class HlsPlayer {
  private video: HTMLVideoElement | null = null;
  private hls: Hls | null = null;
  private options: {
    onStatusChange?: (status: string) => void;
  };

  /**
   * 构造函数
   * @param id 视频元素的 ID
   * @param options 配置选项
   */
  constructor(id: string, options: { onStatusChange?: (status: string) => void } = {}) {
    this.video = document.getElementById(id) as HTMLVideoElement;
    this.options = { ...options };

    if (!this.video) {
      console.error(`Video element with id ${id} not found`);
      return;
    }

    // 检查浏览器是否原生支持 HLS
    if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
      this.options.onStatusChange?.('native');
      return;
    }

    // 检查 Hls.js 是否可用
    if (!Hls.isSupported()) {
      console.error('HLS is not supported in this browser');
      this.options.onStatusChange?.('unsupported');
      return;
    }
  }

  /**
   * 初始化播放器并加载视频流
   * @param url HLS 视频流地址
   */
  /**
   * 检查视频是否正在播放
   */
  isPlaying(): boolean {
    return !!this.video && !this.video.paused;
  }

  initPlayer(url: string): void {
    if (!this.video) return;

    // 如果浏览器原生支持 HLS
    if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
      this.video.src = url;
      this.video.addEventListener('loadedmetadata', () => {
        this.video
          ?.play()
          .then(() => {
            this.options.onStatusChange?.('playing');
          })
          .catch(error => {
            console.error('Error playing video:', error);
            this.options.onStatusChange?.('error');
          });
      });
      return;
    }

    // 使用 hls.js 播放
    if (window.Hls && window.Hls.isSupported()) {
      if (this.hls) {
        this.hls.destroy();
      }

      this.hls = new window.Hls();
      this.hls.loadSource(url);
      this.hls.attachMedia(this.video);
      this.hls.on(window.Hls.Events.MANIFEST_PARSED, () => {
        this.video
          ?.play()
          .then(() => {
            this.options.onStatusChange?.('playing');
          })
          .catch(error => {
            console.error('Error playing video:', error);
            this.options.onStatusChange?.('error');
          });
      });

      this.hls.on(window.Hls.Events.ERROR, (event: any, data: any) => {
        if (data.fatal) {
          switch (data.type) {
            case window.Hls.ErrorTypes.NETWORK_ERROR:
              console.error('HLS network error:', data);
              this.hls.startLoad();
              break;
            case window.Hls.ErrorTypes.MEDIA_ERROR:
              console.error('HLS media error:', data);
              this.hls.recoverMediaError();
              break;
            default:
              console.error('HLS fatal error:', data);
              this.destroy();
              break;
          }
          this.options.onStatusChange?.('error');
        }
      });
    } else {
      console.error('HLS is not supported in this browser');
      this.options.onStatusChange?.('error');
    }
  }

  /**
   * 销毁播放器实例
   */
  destroy(): void {
    if (this.hls) {
      this.hls.destroy();
      this.hls = null;
    }

    if (this.video) {
      this.video.pause();
      this.video.removeAttribute('src');
      this.video.load();
    }
  }

  /**
   * 获取当前视频帧的图像 URL
   * @returns 图像的 Data URL
   */
  getImageUrl(): string | null {
    if (!this.video) return null;

    const canvas = document.createElement('canvas');
    canvas.width = this.video.videoWidth;
    canvas.height = this.video.videoHeight;

    const context = canvas.getContext('2d');
    if (!context) return null;

    context.drawImage(this.video, 0, 0, canvas.width, canvas.height);
    const dataURL = canvas.toDataURL();

    canvas.remove();
    return dataURL;
  }
}

// 为 TypeScript 添加全局 Hls 类型
declare global {
  interface Window {
    Hls: any;
  }
}

export default HlsPlayer;
